﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using PhantomRealm.Common.Utilities;
using System;
using System.Collections.Generic;
using Terraria;
using Terraria.GameContent;
using Terraria.GameContent.Bestiary;
using Terraria.GameContent.ItemDropRules;
using Terraria.ID;
using Terraria.ModLoader;

namespace PhantomRealm.Content.NPCs.Enemies
{
    public class AuroraWraith : ModNPC
    {
        private float auroraTime;
        private readonly List<Vector2> positionHistory = [];
        private const int HISTORY_LENGTH = 6;
        private readonly Color AuroraColor1 = new(0, 143, 233);
        private readonly Color AuroraColor2 = new(0, 255, 255);
        private readonly Color AuroraColor3 = new(9, 231, 167);
        private readonly Color AuroraColor4 = new(0, 255, 100);

        public override void SetStaticDefaults()
        {
            Main.npcFrameCount[NPC.type] = 4;            
        }
        public override void SetDefaults()
        {
            NPC.rarity = 5;
            NPC.width = 40;
            NPC.height = 60;
            NPC.aiStyle = -1;
            NPC.damage = 0;
            NPC.defense = 0;
            NPC.lifeMax = 50;
            NPC.HitSound = SoundID.NPCHit54;
            NPC.DeathSound = SoundID.NPCDeath6;
            NPC.value = 0;
            NPC.noGravity = true;
            NPC.noTileCollide = true;
            NPC.friendly = true;
            NPC.dontTakeDamage = true;
            if (NPC.IsABestiaryIconDummy)
            {
                NPC.color = Color.Lerp(new Color(9, 231, 167), new Color(0, 255, 255),
                    (float)(Math.Sin(Main.GlobalTimeWrappedHourly * 2f) * 0.5f + 0.5f));
            }
        }
        public override void ModifyNPCLoot(NPCLoot npcLoot)
        {
            npcLoot.Add(ItemDropRule.Common(ModContent.ItemType<Items.Materials.AuroraDust>(), 2, 1, 2));
        }
        public override float SpawnChance(NPCSpawnInfo spawnInfo)
        {
            if (spawnInfo.Player.ZoneSnow() && spawnInfo.Player.ZoneAurora() && spawnInfo.Player.IsNight())
            {
                return 0.002f;
            }
            return 0f;
        }

        public override void SetBestiary(BestiaryDatabase database, BestiaryEntry bestiaryEntry)
        {
            bestiaryEntry.Info.AddRange([
                BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Times.NightTime,
                BestiaryDatabaseNPCsPopulator.CommonTags.SpawnConditions.Biomes.Snow,
                new FlavorTextBestiaryInfoElement("Mods.PhantomRealm.NPCs.AuroraWraith.Description")
            ]);
        }

        public override void AI()
        {
            auroraTime += 0.05f;
            if (auroraTime > 1000f) auroraTime = 0f;
            UpdateDirection();
            if (!Main.gameMenu && !Main.dedServ && !NPC.IsABestiaryIconDummy)
            {
                UpdatePositionHistory();
            }
            PeacefulBehavior();
        }

        private void UpdateDirection()
        {
            if (Math.Abs(NPC.velocity.X) > 0.1f)
            {
                NPC.direction = NPC.velocity.X > 0 ? 1 : -1;
                NPC.spriteDirection = NPC.direction;
            }
        }

        private void PeacefulBehavior()
        {
            NPC.velocity *= 0.98f;
            if (Main.rand.NextBool(180))
            {
                NPC.velocity += new Vector2(
                    Main.rand.NextFloat(-0.5f, 0.5f),
                    Main.rand.NextFloat(-0.5f, 0.5f)
                );
                NPC.velocity = Vector2.Clamp(NPC.velocity, new Vector2(-1.5f, -1.5f), new Vector2(1.5f, 1.5f));
            }
            foreach (Player player in Main.player)
            {
                if (player.active && !player.dead)
                {
                    float distance = Vector2.Distance(player.Center, NPC.Center);
                    if (distance < 100f)
                    {
                        Vector2 awayDirection = (NPC.Center - player.Center).SafeNormalize(Vector2.Zero);
                        NPC.velocity += awayDirection * 0.2f;
                    }
                }
            }
        }

        private void UpdatePositionHistory()
        {
            positionHistory.Insert(0, NPC.Center);
            if (positionHistory.Count > HISTORY_LENGTH)
            {
                positionHistory.RemoveAt(positionHistory.Count - 1);
            }
        }

        public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor)
        {
            if (NPC.IsABestiaryIconDummy)
            {
                return true;
            }
            DrawAuroraTrail(spriteBatch, screenPos);
            DrawAuroraBody(spriteBatch, screenPos);
            return false;
        }     
        private void DrawAuroraBody(SpriteBatch spriteBatch, Vector2 screenPos)
        {
            Texture2D texture = TextureAssets.Npc[NPC.type].Value;
            Rectangle frame = NPC.frame;
            Vector2 origin = new Vector2(frame.Width * 0.5f, frame.Height * 0.5f);
            Vector2 drawPos = NPC.Center - screenPos;
            drawPos.Y += NPC.gfxOffY;
            SpriteEffects spriteEffects = NPC.spriteDirection == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
            spriteBatch.End();
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Additive,
                Main.DefaultSamplerState, DepthStencilState.None,
                RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix);
            for (int i = 0; i < 3; i++)
            {
                float timeOffset = auroraTime + i * 0.3f;
                float pulse = (float)Math.Sin(timeOffset * 1.5f) * 0.2f + 0.8f;
                float scaleMultiplier = 1.03f + i * 0.05f;
                float alpha = 0.4f / (i + 1) * pulse;

                Color gradientColor;
                switch (i)
                {
                    case 0:
                        gradientColor = AuroraColor3;
                        break;
                    case 1:
                        float blend1 = (float)Math.Sin(timeOffset * 1.2f) * 0.5f + 0.5f;
                        gradientColor = Color.Lerp(AuroraColor3, AuroraColor2, blend1);
                        break;
                    default:
                        float blend2 = (float)Math.Cos(timeOffset * 1.5f) * 0.5f + 0.5f;
                        gradientColor = Color.Lerp(AuroraColor3, AuroraColor1, blend2);
                        break;
                }
                gradientColor.A = (byte)(alpha * 255);
                Vector2 offset = new Vector2(
                    (float)Math.Sin(timeOffset * 1.5f + i) * 0.5f,
                    (float)Math.Cos(timeOffset * 1.2f + i) * 0.5f
                );

                spriteBatch.Draw(texture, drawPos + offset, frame, gradientColor,
                    NPC.rotation, origin, NPC.scale * scaleMultiplier, spriteEffects, 0f);
            }
            spriteBatch.End();
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend,
                Main.DefaultSamplerState, DepthStencilState.None,
                RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix);
            Color baseColor = AuroraColor3;
            baseColor.A = 120;
            spriteBatch.Draw(texture, drawPos, frame, baseColor,
                NPC.rotation, origin, NPC.scale, spriteEffects, 0f);
        }

        private void DrawAuroraTrail(SpriteBatch spriteBatch, Vector2 screenPos)
        {
            Texture2D texture = TextureAssets.Npc[NPC.type].Value;
            Rectangle frame = NPC.frame;
            Vector2 origin = new Vector2(frame.Width * 0.5f, frame.Height * 0.5f);
            SpriteEffects spriteEffects = NPC.spriteDirection == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
            for (int i = positionHistory.Count - 1; i >= 0; i--)
            {
                float progress = (float)i / HISTORY_LENGTH;
                float alpha = 0.4f * (1f - progress * progress);
                float scale = NPC.scale * (0.7f + 0.2f * progress);

                Color trailColor;
                if (progress < 0.33f)
                {
                    float blend = progress * 3f;
                    trailColor = Color.Lerp(AuroraColor3, AuroraColor2, blend);
                }
                else if (progress < 0.66f)
                {
                    float blend = (progress - 0.33f) * 3f;
                    trailColor = Color.Lerp(AuroraColor2, AuroraColor1, blend);
                }
                else
                {
                    float blend = (progress - 0.66f) * 3f;
                    trailColor = Color.Lerp(AuroraColor1, AuroraColor4, blend);
                }

                trailColor.A = (byte)(alpha * 255);

                Vector2 drawPos = positionHistory[i] - screenPos;
                drawPos.Y += NPC.gfxOffY;

                spriteBatch.Draw(texture, drawPos, frame, trailColor,
                    NPC.rotation, origin, scale, spriteEffects, 0f);
            }
        }

        public override void PostDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor)
        {
            if (NPC.IsABestiaryIconDummy)
            {
                return;
            }
        }
        public override void DrawBehind(int index)
        {
            if (!NPC.IsABestiaryIconDummy)
            {
                Vector3 lightColor = new Vector3(0.035f, 0.91f, 0.65f);
                Lighting.AddLight(NPC.Center, lightColor * 0.4f);
            }
        }
    }
}